﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using nelech.Models.DBModel;
using nelech.Controllers.Utils;
using System.IO;
using System.Xml;
using System.Xml.Linq;

namespace nelech.Controllers
{
    public class ForumController : Controller
    {
        nelechDBEntities db = new nelechDBEntities();
        // GET: /Forum/

        public ActionResult PuzzleTopic(int id)
        {
            var puzzleTopic = db.PuzzleTopic.First(p => p.id == id);
            var listFeedback = db.PuzzleFeedback.Where(p => p.publish == 1 && p.puzzleID == id).ToList();
            var puzzle = new Puzzle() { puzzle = puzzleTopic, listFeedback = listFeedback };
            var puzzles = db.PuzzleTopic.AsEnumerable().Where(p => p.publish == 1 && p.date > DateTime.Now.Date).ToList();
            puzzles = puzzles.OrderBy(p => p.date, new DateComparer()).ToList();
            var i = puzzles.Count - 4 < 0 ? 0 : puzzles.Count - 4;
            var j = puzzles.Count < 4 ? puzzles.Count : 4;
            puzzles = puzzles.GetRange(i, j).ToList();
            ViewData["PuzzlesThumb"] = puzzles;
            return View(puzzle);
        }

        public ActionResult PuzzleMenu()
        {
            var puzzles = db.PuzzleTopic.Where(p => p.date >= DateTime.Now && p.publish == 1).OrderBy(p => p.date).ToList();
            var puzzle = new PuzzleTopic();
            if (puzzles != null && puzzles.Count > 0)
            {
                puzzle = puzzles.First();
            }
            else
            {
                var puzzles1 = db.PuzzleTopic.Where(p => p.publish == 1).OrderByDescending(p => p.id).ToList();
                puzzle = puzzles1.FirstOrDefault();
            }
            return PartialView(puzzle);
        }

        public PartialViewResult NextPuzzles()
        {
            int? i = (int?)Session["PuzzlePointer"] ?? 0;

            var puzzles = db.PuzzleTopic.AsEnumerable().Where(p => p.publish == 1 && p.date < DateTime.Now.Date).ToList();
            puzzles = puzzles.OrderByDescending(p => p.id).ToList();
            if (i == puzzles.Count)
            {
                i = 0;
            }
            int? j = Math.Min(i.Value + 4, puzzles.Count);
            puzzles = puzzles.GetRange(i.Value, (j - i).Value).ToList();

            Session["PuzzlePointer"] = j;
            return PartialView("Puzzle", puzzles);
        }

        public PartialViewResult PrevPuzzles()
        {
            int? i = (int?)Session["PuzzlePointer"] ?? 0;
            var now = DateTime.Now;
            var puzzles = db.PuzzleTopic.Where(p => p.publish == 1 && p.date < now).ToList();
            puzzles = puzzles.OrderByDescending(p => p.date).ToList();
            if (i == 0)
            {
                i = puzzles.Count;
            }
            int? j = Math.Max(i.Value - 4, 0);
            puzzles = puzzles.GetRange(j.Value, (i - j).Value).ToList();

            Session["PuzzlePointer"] = j;
            return PartialView("Puzzle", puzzles);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult CreatePuzzleFeedback([Bind(Exclude = "id, publish, date")]PuzzleFeedback p, int puzzleID)
        {
            if (!ModelState.IsValid)
                return View("PuzzleTopic", p.puzzleID);
            p.publish = 1;

            var t = db.PuzzleTopic.First(r => r.id == puzzleID);
            p.puzzleID = t.id;
            db.AddToPuzzleFeedback(p);
            p.date = DateTime.Now;
            db.SaveChanges();
            return RedirectToAction("PuzzleTopic", "Forum", new { id = t.id });
        }
        public ActionResult AdminListFeedback(int id)
        {
            var listFeedback = db.PuzzleFeedback.Where(p => p.puzzleID == id && p.publish == 1).ToList();
            var topic = db.PuzzleTopic.First(p => p.id == id);
            var puzzle = new Puzzle() { listFeedback = listFeedback, puzzle = topic };
            return View(puzzle);
        }
        public ActionResult AdminDeleteFeedback(int id)
        {
            var feedback = db.PuzzleFeedback.First(p => p.id == id);
            var g = feedback.PuzzleTopic.id;
            db.DeleteObject(feedback);
            db.SaveChanges();

            return RedirectToAction("AdminRecycleBin", new { id = g });
        }
        public ActionResult AdminRecycleFeedback(int id)
        {
            var feedback = db.PuzzleFeedback.First(p => p.id == id);
            feedback.publish = 0;
            db.SaveChanges();
            feedback.PuzzleTopicReference.Load();
            return RedirectToAction("AdminListFeedback", new { id = feedback.PuzzleTopic.id });
        }
        public ActionResult AdminRestoreFeedback(int id)
        {
            var feedback = db.PuzzleFeedback.First(p => p.id == id);
            feedback.publish = 1;
            db.SaveChanges();
            feedback.PuzzleTopicReference.Load();
            return RedirectToAction("AdminListFeedback", new { id = feedback.PuzzleTopic.id });
        }
        public ActionResult AdminRecycleBin(int id)
        {
            return View(db.PuzzleFeedback.Where(p => p.publish == 0 && p.PuzzleTopic.id == id));
        }

        public ActionResult ListCategory()
        {
            return View(db.ForumCategory.Where(p => p.publish == 1));
        }

        public ActionResult CreateCategory()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult CreateCategory([Bind(Exclude = "id, date")] ForumCategory c)
        {
            if (!ModelState.IsValid)
                return View();
            db.AddToForumCategory(c);
            c.publish = 1;
            c.date = DateTime.Now;
            db.SaveChanges();
            return RedirectToAction("ListCategory");
        }
        [Authorize(Users="admin,editor")]
        public ActionResult EditCategory(int id)
        {
            var subject = db.ForumCategory.First(p => p.id == id);
            return View("CreateCategory", subject);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult EditCategory(ForumCategory c)
        {
            if (!ModelState.IsValid)
                return View("CreateCategory");

            // Get the attached entity
            var m = db.ForumCategory.First(r => r.id == c.id);
            c.date = DateTime.Now;

            // apply changes from the detached object to the attached one
            db.ApplyPropertyChanges(m.EntityKey.EntitySetName, c);

            db.SaveChanges();

            return RedirectToAction("ListCategory", "Forum");
        }

        public ActionResult RecycleCategory(int id)
        {
            var t = db.ForumCategory.First(p => p.id == id);
            t.publish = 0;
            foreach (var response in db.Forum.ToList())
            {
                response.ForumCategoryReference.Load();
            }
            var responses = db.Forum.Where(p => p.ForumCategory.id == id).ToList();
            foreach (var response in responses)
            {
                response.publish = 0;
            }
            db.SaveChanges();
            return RedirectToAction("ListCategory", "Forum");
        }
        [Authorize(Users="admin,editor")]
        public ActionResult RecycleBinCategory()
        {
            return View(db.ForumCategory.Where(p => p.publish == 0));
        }
        [Authorize(Users="admin,editor")]
        public ActionResult RestoreCategory(int id)
        {
            var t = db.ForumCategory.First(p => p.id == id);
            t.publish = 1;
            db.SaveChanges();
            return RedirectToAction("RecycleBinCategory", "Forum");
        }
        [Authorize(Users="admin,editor")]
        public ActionResult DeleteCategory(int id)
        {
            db.DeleteObject(db.ForumCategory.First(p => p.id == id));
            db.SaveChanges();
            return RedirectToAction("RecycleBinCategory");

        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult CreateSubject([Bind(Exclude = "c_id, name")]Forum forum, int c_id, string name)
        {
            forum.ForumCategory = db.ForumCategory.First(p => p.id == c_id);
            forum.p_id = 0;
            forum.date = DateTime.Now;
            forum.publish = 1;
            forum.name = name;
            forum.see = 1;
            forum.s_id = 0;
            db.AddToForum(forum);
            db.SaveChanges();
            return RedirectToAction("ListResponseOfCategory", new { id = c_id });
        }
        [Authorize]
        public ActionResult CreateSubject(int id)
        {
            return View(db.ForumCategory.First(p => p.id == id));
        }


        [Authorize]
        public ActionResult CreateResponse1(int p_id)
        {
            var parentRes = db.Forum.First(p => p.id == p_id);
         
            var forumQuote = new ForumQuote { parentRes = parentRes };
            return View("CreateResponse", forumQuote);
        }

        public ActionResult RemoveForumImage(int id)
        {
            var forum = db.Forum.First(p => p.id == id);
            try
            {
                System.IO.File.Delete(Server.MapPath(forum.image));
            }
            catch (Exception e)
            {
            }
            forum.image = string.Empty;
            db.SaveChanges();
            return Redirect(Request.UrlReferrer.ToString());
        }
        private void AddForumImages(Forum p)
        {
            HttpPostedFileBase image = Request.Files["image"];
            if (image != null && !string.IsNullOrEmpty(image.FileName))
            {
                var filename = SharedUtils.GetUniqueFileName(image.FileName);
                var extension = Path.GetExtension(image.FileName);
                var img = new Image
                {
                    path = extension.Equals(".swf", StringComparison.OrdinalIgnoreCase) ?
                    SharedUtils.SaveImage(image.InputStream, "/Forum", filename, extension, Server) :
                    SharedUtils.SaveImage(image.InputStream, "/Forum", filename, extension, Server, 100L, false)
                };
                p.image = img.path;
            }

        }

        public ActionResult NextPuzzleTopic(int id)
        {
            var puzzle = db.PuzzleTopic.Where(p => p.id > id && p.publish == 1).OrderBy(p => p.id).FirstOrDefault();
            if (puzzle != null)
            {
                return RedirectToAction("PuzzleTopic", new { id = puzzle.id });
            }
            else
            {
                return RedirectToAction("PuzzleTopic", new { id = id });
            }
        }
        public ActionResult PrePuzzleTopic(int id)
        {
            var puzzle = db.PuzzleTopic.Where(p => p.id < id && p.publish == 1).OrderByDescending(p => p.id).FirstOrDefault();
            if (puzzle != null)
            {
                return RedirectToAction("PuzzleTopic", new { id = puzzle.id });
            }
            else
            {
                return RedirectToAction("PuzzleTopic", new { id = id });
            }
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult CreateResponse([Bind(Exclude = "id, date, name")]Forum forum, int c_id, string name)
        {
            try
            {
                forum.ForumCategory = db.ForumCategory.First(p => p.id == c_id);
                if (db.BlockedUsers.Any(p => p.userName == name))
                    return RedirectToAction("ListResponseOfCategory", new { id = forum.p_id });

                forum.date = DateTime.Now;
                //var doc = new XDocument();
                //.LoadXml(forum.movie);
                //var iframe = doc.FirstChild;
                //iframe.Attributes["height"].Value = "100";
                //iframe.Attributes["width"].Value = "150";
                //forum.movie = iframe.ToString();
                forum.publish = 1;
                db.AddToForum(forum);
                forum.name = name;
                AddForumImages(forum);
                db.SaveChanges();

                return RedirectToAction("ListResponseOfCategory", new { id = forum.c_id });
            }
            catch (ArgumentException e)
            {
                return View("FileUploadError", e.Message);
            }
        }


        public ActionResult ListCategoryForum()
        {
            var categories = db.ForumCategory.Where(p => p.publish == 1);
            var categoriesCount = new List<CategoryCount>();

            foreach (var category in categories)
            {
                var categoryCount = new CategoryCount();
                categoryCount.category = category;
                categoryCount.sum = category.Forum.Count();
                categoriesCount.Add(categoryCount);
            }
            return View(categoriesCount);
        }

        public ActionResult ListFirstResponseOfCategory(int id)
        {
            var category = db.ForumCategory.First(p => p.id == id);
            category.see++;
            db.SaveChanges();
            var forumResponse = new ForumResponse()
            {
                category = category,
                responses = db.Forum.Where(p => p.ForumCategory.id == id && p.p_id == 0 && p.publish == 1).ToList()
            };
            return View(forumResponse);
        }


        public ActionResult ListResponseOfCategory(int id)
        {
            var category = db.ForumCategory.First(p => p.id == id);
            var respones = db.Forum.Where(p => p.c_id == category.id && p.publish == 1).ToList();

            var listResponse = new ForumResponse() { category = category, responses = respones };
            return View(listResponse);
        }

        [Authorize(Users="admin,editor")]
        public ActionResult EditResponse(int id)
        {
            var forum = db.Forum.First(p => p.id == id);
            forum.ForumCategoryReference.Load();
            return View(forum);
        }
        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult EditResponse([Bind(Exclude = "c_id")]Forum f, int c_id, bool block)
        {

            if (!ModelState.IsValid)
                return View("EditResponse");
            var response = db.Forum.First(p => p.id == f.id);

            // Get the attached entity
            if (block)
            {
                var blockUser = new BlockedUsers() { userName = response.name };
                db.AddToBlockedUsers(blockUser);
                var blockResponse = db.Forum.Where(p => p.name == response.name).ToList();
                foreach (var blockR in blockResponse)
                {
                    DeleteResponse1(blockR.id);
                    db.DeleteObject(blockR);
                }

            }
            else
            {

                // apply changes from the detached object to the attached one
                db.ApplyPropertyChanges(response.EntityKey.EntitySetName, f);
                response.ForumCategory = db.ForumCategory.First(p => p.id == c_id);
                response.date = DateTime.Now;
            }
            db.SaveChanges();

            return RedirectToAction("ListSubjectAdmin", new { id = c_id });

        }
        [Authorize(Users="admin,editor")]
        public ActionResult DeleteSubject(int id)
        {
            var subject = db.Forum.First(p => p.id == id);
            subject.ForumCategoryReference.Load();
            var categoryId = subject.ForumCategory.id;
            var responses = db.Forum.Where(p => p.p_id == subject.id);
            foreach (var response in responses)
            {
                db.DeleteObject(response);
            }
            db.DeleteObject(subject);
            db.SaveChanges();
            return RedirectToAction("ListSubjectAdmin", new { id = categoryId });
        }

        public ActionResult RestoreResponse(int id)
        {
            var response = db.Forum.First(p => p.id == id);
            response.publish = 1;
            db.SaveChanges();
            response.ForumCategoryReference.Load();
            return RedirectToAction("ListSubjectAdmin", new { id = response.ForumCategory.id });
        }
        public ActionResult RecycleResponse(int id)
        {
            var response = db.Forum.First(p => p.id == id);
            response.publish = 0;
            db.SaveChanges();
            response.ForumCategoryReference.Load();
            return RedirectToAction("ListSubjectAdmin", new { id = response.ForumCategory.id });
        }
        [Authorize(Users="admin,editor")]
        public ActionResult DeleteResponse(int id)
        {
            var response = db.Forum.First(p => p.id == id);
            DeleteResponse1(id);
            response.ForumCategoryReference.Load();
            var categoryID = response.ForumCategory.id;
            db.DeleteObject(response);
            db.SaveChanges();

            return RedirectToAction("ListSubjectAdmin", new { id = categoryID });
        }
        [Authorize(Users="admin,editor")]
        private void DeleteResponse1(int id)
        {
            var response = db.Forum.First(p => p.id == id);
            if (db.Forum.Any(p => p.p_id == id))
            {
                var response1 = db.Forum.First(p => p.p_id == id);
                if (response.p_id == null || response.p_id == 0)
                {
                    response1.p_id = 0;
                }
                else
                {
                    var response0 = db.Forum.First(p => p.id == response.p_id);
                    response1.p_id = response0.id;
                }
            }

        }

        public ActionResult ListSubjectAdmin(int id)
        {
            var category = db.ForumCategory.First(p => p.id == id);
            var responses = db.Forum.Where(p => p.ForumCategory.id == id).ToList();
            var listResponse = new ForumResponse() { category = category, responses = responses };
            return View(listResponse);
        }

        //public ActionResult ListResponseAdmin(int id)
        //{
        //    var subject = db.Forum.First(p => p.id == id);
        //    var responses = db.Forum.Where(p => p.p_id == id).ToList();
        //    var responsesToResponses = new List<Forum>();
        //    var responsesToResponses1 = new List<Forum>();
        //    var responsesToResponses2 = new List<Forum>();
        //    foreach (var res in responses)
        //    {
        //        var tatRes1 = db.Forum.Where(p => p.p_id == res.id);
        //        foreach (var tat in tatRes1)
        //        {
        //            responsesToResponses.Add(tat);
        //        }
        //    }
        //    foreach (var res in responsesToResponses)
        //    {
        //        var tatRes2 = db.Forum.Where(p => p.p_id == res.id);
        //        foreach (var tat in tatRes2)
        //        {
        //            responsesToResponses1.Add(tat);
        //        }
        //    }
        //    foreach (var res in responsesToResponses1)
        //    {
        //        var tatRes = db.Forum.Where(p => p.p_id == res.id);
        //        foreach (var tat in tatRes)
        //        {
        //            responsesToResponses2.Add(tat);
        //        }
        //    }
        //    responses.AddRange(responsesToResponses);
        //    responses.AddRange(responsesToResponses1);
        //    responses.AddRange(responsesToResponses2);
        //    var listResponses = new ForumResponse() { subject = subject, responses = responses };
        //    return View(listResponses);
        //}

        public ActionResult SearchForum(string searchString)
        {
            var forums = db.Forum.ToList();
            forums = SharedUtils.FreeSearchForum(forums, searchString);
            if (forums == null)
            {
                return View();
            }
            if (forums.Count() < 0)
            {
                ViewData["EmptyForum"] = "לא נמצאו תוצאות";
            }
            var searchForumViewList = new List<SearchForumView>();
            foreach (var forum in forums)
            {
                forum.ForumCategoryReference.Load();
                var category = db.ForumCategory.First(p => p.id == forum.c_id);
               
                var searchForumView = new SearchForumView() {forum = forum, category = category, subject = db.Forum.FirstOrDefault(p => p.id == forum.p_id) };
                searchForumViewList.Add(searchForumView);
            }
            return View(searchForumViewList);
        }

        public ActionResult ListFeedback()
        {
            var feedback = ViewData["FeedBack"] as Feedbacks;
            var feedbacks = db.Feedback.Where(p => p.parent_id == feedback.parentId && p.FeedbackType.id == feedback.type);
            ViewData["type"] = feedback.type;
            ViewData["parentId"] = feedback.parentId;
            return PartialView("ListFeedback", feedbacks);
        }

        public ActionResult CreateFeedback(int type, int parentId)
        {
            ViewData["type"] = type;
            ViewData["parentId"] = parentId;
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult CreateFeedback([Bind(Exclude = "id")]Feedback feedback, int type)
        {
            if (!ModelState.IsValid)
                return View();
            db.AddToFeedback(feedback);
            feedback.FeedbackType = db.FeedbackType.First(p => p.id == type);
            feedback.date = DateTime.Now;
            db.SaveChanges();
            switch (type)
            {
                case 1:
                default:
                    return RedirectToAction("TrackInfo", "Track", new { id = feedback.parent_id });
                case 2:
                    return RedirectToAction("PlaceInfo", "Place", new { id = feedback.parent_id });
                case 3:
                    return RedirectToAction("SpringInfo", "Place", new { id = feedback.parent_id });
                case 4:
                    return RedirectToAction("ZimerInfo", "Track", new { id = feedback.parent_id });
            }
        }

        public ActionResult ForumMenu()
        {
            var category = new ForumCategory();
            var subject = new Forum();
            if (db.Forum.Where(p => p.publish == 1 && p.p_id == 0).ToList().Count() < 1)
            {
                category = db.ForumCategory.Where(p => p.publish == 1).AsEnumerable().OrderByDescending(p => p.id).First();
                subject = null;
            }
            else
            {
                subject = db.Forum.Where(p => p.publish == 1).AsEnumerable().OrderByDescending(p => p.id).First();
                subject.ForumCategoryReference.Load();
                category = db.ForumCategory.First(p => p.id == subject.ForumCategory.id);
               
            }
            var lastForum = new ForumResponse() { category = category, subject = subject };
            return PartialView(lastForum);

        }
    }
}
